home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / DJLSR106.ARJ / OBSTACK.CC < prev    next >
C/C++ Source or Header  |  1992-03-30  |  4KB  |  124 lines

  1. /* 
  2. Copyright (C) 1988 Free Software Foundation
  3.     written by Doug Lea (dl@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17.  
  18. #ifdef __GNUG__
  19. #pragma implementation "_Obstack.h"
  20. #endif
  21. #include <values.h>
  22. #include <builtin.h>
  23. #include <_Obstack.h>
  24.  
  25. Obstack::Obstack(int size, int alignment)
  26. {
  27.   alignmentmask = alignment - 1;
  28.   chunksize = size;
  29.   chunk = 0;
  30.   nextfree = objectbase = 0;
  31.   chunklimit = 0;
  32. }
  33.  
  34. void Obstack::_free(void* obj)
  35. {
  36.   _obstack_chunk*  lp;
  37.   _obstack_chunk*  plp;
  38.  
  39.   lp = chunk;
  40.   while (lp != 0 && ((void*)lp > obj || (void*)(lp)->limit < obj))
  41.   {
  42.     plp = lp -> prev;
  43.     delete(lp);
  44.     lp = plp;
  45.   }
  46.   if (lp)
  47.   {
  48.     objectbase = nextfree = (char *)(obj);
  49.     chunklimit = lp->limit;
  50.     chunk = lp;
  51.   }
  52.   else if (obj != 0)
  53.     (*lib_error_handler)("Obstack", "deletion of nonexistent obj");
  54. }
  55.  
  56. void Obstack::newchunk(int size)
  57. {
  58.   _obstack_chunk*    old_chunk = chunk;
  59.   _obstack_chunk*    new_chunk;
  60.   long    new_size;
  61.   int obj_size = nextfree - objectbase;
  62.  
  63.   new_size = (obj_size + size) << 1;
  64.   if (new_size < chunksize)
  65.     new_size = chunksize;
  66.  
  67.   new_chunk = chunk = (_obstack_chunk*)(new char[new_size]);
  68.   new_chunk->prev = old_chunk;
  69.   new_chunk->limit = chunklimit = (char *) new_chunk + new_size;
  70.  
  71.   bcopy((void*)objectbase, (void*)new_chunk->contents, obj_size);
  72.   objectbase = new_chunk->contents;
  73.   nextfree = objectbase + obj_size;
  74. }
  75.  
  76. void* Obstack::finish()
  77. {
  78.   void* value = (void*) objectbase;
  79.   nextfree = (char*)((int)(nextfree + alignmentmask) & ~(alignmentmask));
  80.   if (nextfree - (char*)chunk > chunklimit - (char*)chunk)
  81.     nextfree = chunklimit;
  82.   objectbase = nextfree;
  83.   return value;
  84. }
  85.  
  86. int Obstack::contains(void* obj) // true if obj somewhere in Obstack
  87. {
  88.   for (_obstack_chunk* ch = chunk; 
  89.        ch != 0 && (obj < (void*)ch || obj >= (void*)(ch->limit)); 
  90.        ch = ch->prev);
  91.  
  92.   return ch != 0;
  93. }
  94.          
  95. int Obstack::OK()
  96. {
  97.   int v = chunksize > 0;        // valid size
  98.   v &= alignmentmask != 0;      // and alignment
  99.   v &= chunk != 0;
  100.   v &= objectbase >= chunk->contents;
  101.   v &= nextfree >= objectbase;
  102.   v &= nextfree <= chunklimit;
  103.   v &= chunklimit == chunk->limit;
  104.   _obstack_chunk* p = chunk;
  105.   // allow lots of chances to find bottom!
  106.   long x = MAXLONG;
  107.   while (p != 0 && x != 0) { --x; p = p->prev; }
  108.   v &= x > 0;
  109.   if (!v) 
  110.     (*lib_error_handler)("Obstack", "invariant failure");
  111.   return v;
  112. }
  113.  
  114.  
  115. #ifdef VMS
  116. #include "libgxx-io-ob.cc"
  117. // The reason that this needs to be included is that if the modules for libg++
  118. // are placed in a library, and libgxx-ob-io is in a seperate module, then
  119. // that module contains only two symbols -  the contstructor and destructor.
  120. // they are not called explicitly anywhere else, so that module is not linked
  121. // in, and the contstructor is not called.  Chaos ensues.
  122. #endif
  123.  
  124.